package com.bingxue.edu.framework.storage;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.EscapeUtil;
import cn.hutool.core.util.StrUtil;
import com.bingxue.edu.common.enums.FileTypeEnum;
import com.bingxue.edu.management.auth.EmployeeAuthUtil;
import com.bingxue.edu.management.system.model.entity.File;
import com.bingxue.edu.management.system.model.entity.Storage;
import com.bingxue.edu.management.system.service.FileService;
import com.bingxue.edu.management.system.service.StorageService;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.recorder.FileRecorder;
import org.dromara.x.file.storage.core.upload.FilePartInfo;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.Optional;

import static com.bingxue.edu.management.system.model.entity.table.FileTableDef.FILE;

/**
 * 文件记录实现类
 *
 * @author panbo
 * @since 2024/07/24
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class FileRecorderImpl implements FileRecorder {

    @Lazy
    @Resource
    private FileService fileService;
    @Lazy
    @Resource
    private StorageService storageService;


    @Override
    public boolean save(FileInfo fileInfo) {
        File file = new File();
        String originalFilename = EscapeUtil.unescape(fileInfo.getOriginalFilename());
        file.setName(StrUtil.contains(originalFilename, StrUtil.DOT)
            ? StrUtil.subBefore(originalFilename, StrUtil.DOT, true)
            : originalFilename);
        file.setFileUrl(fileInfo.getUrl());
        file.setFileSize(fileInfo.getSize());
        file.setExtension(fileInfo.getExt());
        file.setFileType(FileTypeEnum.getByExtension(file.getExtension()));
        file.setThumbnailUrl(fileInfo.getThUrl());
        file.setThumbnailSize(fileInfo.getThSize());
        Storage storage = (Storage)fileInfo.getAttr().get(ClassUtil.getClassName(Storage.class, false));
        file.setStorageId(storage.getId());
        file.setCreateTime(DateUtil.toLocalDateTime(fileInfo.getCreateTime()));
        file.setUpdateUser(EmployeeAuthUtil.getCurrentUserId());
        file.setUpdateTime(file.getCreateTime());
        fileService.save(file);
        log.info("保存文件成功, {}", file);
        return true;
    }

    @Override
    public FileInfo getByUrl(String url) {
        File file = this.getFileByUrl(url);
        if (null == file) {
            return null;
        }
        return file.toFileInfo(storageService.getById(file.getStorageId()).getCode());
    }

    @Override
    public boolean delete(String url) {
        File file = this.getFileByUrl(url);
        return fileService.updateChain().where(FILE.FILE_URL.eq(file.getFileUrl())).remove();
    }

    @Override
    public void update(FileInfo fileInfo) {
        /* 不使用分片功能则无需重写 */
    }

    @Override
    public void saveFilePart(FilePartInfo filePartInfo) {
        /* 不使用分片功能则无需重写 */
    }

    @Override
    public void deleteFilePartByUploadId(String s) {
        /* 不使用分片功能则无需重写 */
    }

    /**
     * 根据 URL 查询文件
     *
     * @param url URL
     * @return 文件信息
     */
    private File getFileByUrl(String url) {
        Optional<File> fileOptional = fileService.queryChain().where(FILE.FILE_URL.eq(url)).oneOpt();
        return fileOptional.orElseGet(() -> fileService.queryChain()
                .where(FILE.FILE_URL.likeLeft(StrUtil.subAfter(url, StrUtil.SLASH, true)))
                .oneOpt()
                .orElse(null)
        );
    }
}
